#pragma once

#include <stdlib.h>
#include <ucontext.h>
#include <exception>
#include <string>

using std::string;

typedef void (*ProcFunc)(void * arg);
// UContext 运行结束后，暂没有结束回调

struct StackException: std::exception
{
    StackException(const string& msg):m_msg(msg)
    {}

    ~StackException() throw ()
    {}

    const char* what() const throw ()
    {
        return m_msg.c_str();
    }

    string  m_msg;
};

enum UC_STAT
{
    UC_INIT = 0,
    UC_RUNNING,
    UC_YIELD,
    UC_END
};

struct UContext
{
    UContext(size_t stacksize, ProcFunc func,void* args);
    ~UContext();

    ucontext_t  m_context;

    ProcFunc    m_func;
    void        *m_args;
    size_t      m_stacksize;
    void*       m_stack;

    UC_STAT     m_stat;
public:
    bool        resume();
    bool        yield();

    static UContext* create(size_t stacksize, ProcFunc func,void* args);
private:
    static void run(UContext* ptrUContext);
    static ucontext_t* get_init_context();
};



